package com.chen.tliaswebtest.service.impl;

import com.chen.tliaswebtest.exception.TliasException;
import com.chen.tliaswebtest.mapper.ClazzMapper;
import com.chen.tliaswebtest.mapper.EmpExpressMapper;
import com.chen.tliaswebtest.mapper.EmpMapper;
import com.chen.tliaswebtest.pojo.Emp;
import com.chen.tliaswebtest.pojo.EmpDTO;
import com.chen.tliaswebtest.pojo.EmpExpress;
import com.chen.tliaswebtest.pojo.PageResult;
import com.chen.tliaswebtest.service.EmpService;
import com.chen.tliaswebtest.utils.EscapeUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.page.PageMethod;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

/**
 * @author chen
 * @version 1.0
 * @create_date 2025/7/24
 * 员工管理模块业务逻辑层实现类
 */
@Service
// spring事务默认只回滚运行时异常，编译时异常不会回滚
// 指定属性rollbackFor = {Exception.class}，可以捕获所有异常进行回滚
@Transactional(rollbackFor = {Exception.class})
public class EmpServiceImpl implements EmpService {

    private final EmpMapper empMapper;
    private final EmpExpressMapper empExpressMapper;
    private final ClazzMapper clazzMapper;

    public EmpServiceImpl(EmpMapper empMapper, EmpExpressMapper empExpressMapper, ClazzMapper clazzMapper) {
        this.empMapper = empMapper;
        this.empExpressMapper = empExpressMapper;
        this.clazzMapper = clazzMapper;
    }

    @Override
    public PageResult listByPage(String name, Integer gender, LocalDate begin,
                                 LocalDate end, Integer page, Integer pageSize) {
        // 设置分页数
        PageMethod.startPage(page, pageSize);
        List<Emp> empList = empMapper.selectAllByPage(EscapeUtils.escapeLikePattern(name), gender, begin, end, page, pageSize);
        Page<Emp> result = (Page<Emp>) empList;
        return PageResult.builder().total(result.getTotal()).rows(result.getResult()).build();
    }

    @Override
    public void removeByIds(List<Integer> ids) {
        // 查询是否有管理的班级
        ids.forEach(id -> {
            if (clazzMapper.countByMasterIds(id) > 0) {
                throw new TliasException("员工ID: " + id + " 有班级信息，请先删除或修改员工管理的班级信息");
            }
        });

        // 删除员工对应的学历信息
        empExpressMapper.deleteEmpExprByIds(ids);
        // 删除员工信息
        empMapper.deleteEmpByIds(ids);
    }

    @Override
    public void addEmp(EmpDTO inDTO) {
        List<Emp> emps = empMapper.selectAll();
        if (emps.stream().map(Emp::getUsername).anyMatch(s -> s.equals(inDTO.getUsername()))) {
            throw new TliasException("用户名已存在!");
        }
        // 添加更新创建信息
        inDTO.setCreateTime(LocalDateTime.now());
        inDTO.setUpdateTime(LocalDateTime.now());
        // 添加员工信息
        Emp resultEmp = mapToEmp(inDTO);
        empMapper.add(resultEmp);

        List<EmpExpress> exprList = inDTO.getExprList();
        // 如果没有学历信息，则返回
        if (CollectionUtils.isEmpty(exprList)) {
            return;
        }
        // 添加员工学历信息
        empExpressMapper.addEmpExpresess(resultEmp.getId(), inDTO.getExprList());
    }

    @Override
    public EmpDTO getEmpById(Integer id) {
        List<EmpExpress> empExpr = empExpressMapper.selectEmpExprById(id);
        Emp emp = empMapper.selectEmpById(id);
        EmpDTO empDTO = mapToEmpDto(emp);
        empDTO.setExprList(empExpr);
        return empDTO;
    }

    @Override
    public void updateEmp(EmpDTO inDTO) {

        // 更新员工表
        inDTO.setUpdateTime(LocalDateTime.now());
        Emp emp = mapToEmp(inDTO);
        empMapper.update(emp);

        // 更新员工工作经历信息
        // 首先删除员工工作经历信息
        empExpressMapper.deleteEmpExprByIds(List.of(emp.getId()));
        List<EmpExpress> exprList = inDTO.getExprList();
        // 如果没有学历信息，则返回
        if (CollectionUtils.isEmpty(exprList)) {
            return;
        }
        // 添加员工工作经历信息
        empExpressMapper.addEmpExpresess(emp.getId(), inDTO.getExprList());
    }

    @Override
    public List<Emp> getAllEmp() {
        return empMapper.selectAll();
    }

    // EmpDto -> Emp 数据转换
    private Emp mapToEmp(EmpDTO inDTO) {
        return Emp.builder()
                .id(inDTO.getId())
                .username(inDTO.getUsername())
                .password(inDTO.getPassword())
                .name(inDTO.getName())
                .gender(inDTO.getGender())
                .image(inDTO.getImage())
                .job(inDTO.getJob())
                .phone(inDTO.getPhone())
                .deptId(inDTO.getDeptId())
                .salary(inDTO.getSalary())
                .updateTime(inDTO.getUpdateTime())
                .createTime(inDTO.getCreateTime())
                .entryDate(inDTO.getEntryDate())
                .build();
    }

    // EmpDto -> Emp 数据转换
    private EmpDTO mapToEmpDto(Emp inDTO) {
        return EmpDTO.builder()
                .id(inDTO.getId())
                .username(inDTO.getUsername())
                .password(inDTO.getPassword())
                .name(inDTO.getName())
                .gender(inDTO.getGender())
                .image(inDTO.getImage())
                .job(inDTO.getJob())
                .phone(inDTO.getPhone())
                .deptId(inDTO.getDeptId())
                .salary(inDTO.getSalary())
                .updateTime(inDTO.getUpdateTime())
                .createTime(inDTO.getCreateTime())
                .entryDate(inDTO.getEntryDate())
                .build();
    }
}
